<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Open聊天室</title>
  <link rel="shortcut icon" href="./favicon.ico">
  <link rel="stylesheet" href="css/index.css">
</head>

<body>
  <div class="box">
    <!-- 左 -->
    <div class="left">
      <h2>在线用户</h2>
      <ul>
        <!-- <li><a href="javascript:">用户2</a></li>
        <li class="active"><a href="javascript:">用户3</a></li> -->
      </ul>
    </div>
    <!-- 右 -->
    <div class="right">
      <div class="open">Open聊天室</div>
      <div class="items"></div>
    </div>
  </div>
  <script src="http://localhost/socket.io/socket.io.js"></script>
  <script src="lib/jquery.js"></script>
  <script>
    var socket;
    // 发送ajax请求，鉴权
    $.ajax({
      url: 'http://localhost/authentication',
      headers: {
        "Authorization": sessionStorage.getItem("token")//此处放置请求到的用户token
      },
      success: handler
    })

    /**
     * 鉴权处理程序
     */
    function handler(response) {
      if (!response.isOk) {
        // 没有权限
        alert(response.message)
        location.href = './login.html'
      } else {
        // socket处理程序
        socketHandler(response.nickname);
      }
    }

    /**
     * socket处理
    */
    function socketHandler(nickname) {
      // 客户端创建socket对象，并配置连接服务器url
      socket = io('http://localhost');
      socket.firstOnline = true;
      socket.nickname = nickname;
      // 发送过去该客户端的名字-用户注册
      socket.emit('create', nickname)
      // 监听服务端注册消息-用户上线下线通知
      socket.on('create', function (data) {
        if (socket.firstOnline) {  // 第一次上线或刷新时获取用户列表
          getUserList()
          socket.firstOnline = false;
        }
        else {   // 其他情况-提示用户上线下线，并设置添加或删除对用的用户列表
          if (data.online) {  // 用户上线
            // 添加一个用户展示项
            $('.left ul').append('<li id="' + data.id + '" toUser="' + data.nickname + '"><a href="javascript:">【私聊】-' + data.nickname + '</a>')
            // 添加一个对话框展示项
            createDialog(data.nickname, data.id)
          } else {    // 用户下线
            $(`li[id=${data.id}]`).remove();
            $(`div[itemid=${data.id}]`).remove();
          }
          var $tip = $('<div class="tip">' + data.message + '</div>')
          $tip.height(0)
          $('body').append($tip);
          $tip.animate({ height: 100 }, 500).delay(2000).animate({ height: 0 }, 500, function () { $(this).remove() })
        }
      })
      // 监听服务端回复的消息
      socket.on('message', function (data) {
        showMessage(data);
      })
    }

    /**
     * 获取在线用户
     */
    function getUserList() {
      $.ajax({
        url: 'http://localhost/userlist',
        cache: false,
        headers: {
          "Authorization": sessionStorage.getItem("token")//此处放置请求到的用户token
        },
        success: function (data) {
          // 创建用户列表
          createUserList(data)
        }
      })
    }

    /**
     * 创建用户列表
    */
    function createUserList(list) {
      $('.left ul').append('<li id="all" toUser="所有人"><a href="javascript:">【群聊】-所有人</a>')
      createDialog('所有人', 'all')
      // 用户列表
      for (var i = 0; i < list.length; i++) {
        var title = '';
        if (list[i].nickname == socket.nickname) {
          title = '自己'
        }
        $('.left ul').append('<li id="' + list[i].id + '" toUser="' + list[i].nickname + '"><a href="javascript:">【私聊】-' + list[i].nickname + `${title == "" ? "" : ('(' + title + ')')}` + '</a>')
        // 创建对话框
        createDialog(list[i].nickname, list[i].id)
      }
    }

    /*
     * 创建聊天对话框
    */
    function createDialog(nickname, id) {
      var html = `<div class="item" itemid="${id}">
                  <!-- 聊天的用户标题 -->
                  <h2>${nickname}</h2>
                  <!-- 聊天记录 -->
                  <div class="talk">
                    <ul>
                    </ul>
                  </div>
                  <!-- 图片工具 -->
                  <a href="javascript:" class="photo">照片▩</a>
                  <!-- 文件 -->
                  <input type="file" class="file">
                  <!-- 文本域 -->
                  <textarea class="message" placeholder="请输入发送消息"></textarea>
                  <!-- 发送按钮 -->
                  <a class="send" toUser="${nickname}" href="javascript:">发送</a>
                </div>
              `
      $('.right .items').append(html)

    }

    /*
    *  点击用户列表项，显示对话框
    */
    (function clickUserHandler() {
      $('.left').on('click', 'li', function () {
        var index = $(this).index();
        $(this).addClass('active').siblings().removeClass('active');
        $('.right .open').hide();
        $('.right .items .item').eq(index).show(300).siblings().hide()
      })
    })();

    /*
    * 发送消息-文本
    */
    !function () {
      $('.items').on('click', '.send', function () {
        var $item = $(this).parent();
        // 获取文本域中的值
        var val = $item.find('textarea').val()
        if (val.trim().length == 0) {
          return alert('不能发送空文本')
        }
        // 获取发送对象用户
        var toUser = $(this).attr('toUser');
        socket.emit('message', { type: 'text', value: val, toUser: toUser, id: $item.attr('itemid') })
        // 在对话框中显示自己发送的消息
        $item.find('.talk ul').append(`
                      <li class="own">
                        <span class="name">我</span>
                        <div class="content">${val}</div>
                      </li>
        `);
        $item.find('li').last()[0].scrollIntoView(true)
        $item.find('textarea').val('')
      })
    }()

    /*
    * 发送图片-图片
    */
    !function () {
      $('.right').on('click', '.photo', function () {
        var $item = $(this).parent();
        var $fileDom = $(this).next();
        // 触发文件组件
        $fileDom.trigger('click');
        // 监听文件控件的change事件，并
        $fileDom.on('change', function () {
          // 获取发送对象用户
          var toUser = $(this).attr('toUser');
          // 获取读取的文件
          var file = this.files[0];
          // 创建fileReader对象
          var reader = new FileReader();
          // 读取文件内容
          reader.readAsDataURL(file)
          // 读物完毕后，发送到服务端
          reader.onload = function (ev) {
            // console.log(reader.result)
            // 发送文件数据
            // socket.emit('message',reader.result)
            socket.emit('message', { type: 'photo', value: reader.result, toUser: toUser, id: $item.attr('itemid') })
            // 在本对话框中显示出自己发送的消息
            // 在对话框中显示自己发送的消息
            $item.find('.talk ul').append(`
                          <li class="own">
                            <span class="name">我</span>
                            <div class="content"><img src="${reader.result}" /></div>
                          </li>
            `);
            $item.find('li').last()[0].scrollIntoView(true)
            $fileDom.off('change');
          }
        })
      })
    }()


    /*
     * 展示服务端回复的消息
    */
    function showMessage(data) {
      console.log(data)
      var $item = $('.item[itemid=' + data.sendId + ']');
      // 发送的是文字
      if (data.type == 'text') {
        $item.find('.talk ul').append(`
          <li class="other">
              <span class="name">${data.sendName}</span>
              <div class="content">${data.value}</div>
          </li> 
      `)
        $item.find('.talk ul li').last()[0].scrollIntoView(true);
      } else {
        // 发送的是图片链接
        $item.find('.talk ul').append(`
          <li class="other">
              <span class="name">${data.sendName}</span>
              <div class="content"><img src="${data.value}"></div>
          </li> 
      `)
        $item.find('.talk ul li').last()[0].scrollIntoView(true);
      }
      var $tip = $(`<div class="tip">【${data.sendName}】发来一条新消息</div>`)
      $tip.height(0)
      $('body').append($tip);
      $tip.animate({ height: 100 }, 500).delay(2000).animate({ height: 0 }, 500, function () { $(this).remove() })
    }
  </script>
</body>

</html>